package com.aizuda.boot.modules.file.controller;

import cn.hutool.http.Header;
import com.aizuda.boot.modules.business.contract.dto.SingleResponse;
import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.file.domain.vo.FileDownloadVO;
import com.aizuda.boot.modules.file.domain.vo.FileUploadVO;
import com.aizuda.boot.modules.file.domain.vo.FileVO;
import com.aizuda.boot.modules.file.service.IFileInfoService;
import com.aizuda.boot.modules.file.util.FileResponseUtil;
import com.aizuda.core.api.ApiController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * @author hjw
 * @description 文件Controller
 * @date 2025年06月16日 17:50
 */
@RestController
@Tag(name = "文件相关接口", description = "文件相关接口")
@Slf4j
public class FileController extends ApiController {
    @Autowired
    private IFileInfoService fileService;

    @Operation(summary = "文件上传 ")
    @PostMapping("/file/upload")
    public SingleResponse<FileUploadVO> upload(
            @RequestParam
            @Parameter(description = "上传的文件", required = true)
            MultipartFile file,
            @Parameter(description = "1:通用文件文件夹;2:合同文件夹;3:附件文件夹;4:评论文件夹;5:模版文件夹", required = true, example = "2")
            @RequestParam Integer folder) {
        UserInfo currentUser = AuthUtil.getCurrentUser();

        return fileService.fileUpload(file, folder, currentUser);
    }

    @Operation(summary = "文件上传(通过URL) ")
    @PostMapping("/file/uploadByUrl")
    public SingleResponse<FileUploadVO> uploadByUrl(
            @RequestParam
            @Parameter(description = "上传的文件的url", required = true)
            String sourceUrl,
            @Parameter(description = "1:通用文件文件夹;2:合同文件夹;3:附件文件夹;4:评论文件夹;5:模版文件夹", required = true, example = "2")
            @RequestParam Integer folder) {
        UserInfo currentUser = AuthUtil.getCurrentUser();

        return fileService.fileUpload(sourceUrl, folder, currentUser);
    }


    @Operation(summary = "获取文件URL：根据fileKey ")
    @GetMapping("/file/getFileUrl")
    public SingleResponse<String> getUrl(@Parameter(name = "文件Key", required = true)
                                         @RequestParam String fileKey) {
        return fileService.getFileUrl(fileKey);
    }

    @Operation(summary = "文件下载：根据fileKey ")
    @GetMapping("/file/download")
    public void downLoad(@Parameter(name = "文件Key", required = true)
                         @RequestParam String fileKey, HttpServletRequest request,
                         HttpServletResponse response) throws IOException {
        String userAgent = request.getHeader(Header.USER_AGENT.getValue());
        SingleResponse<FileDownloadVO> downloadFileResult = fileService.getDownloadFile(fileKey, userAgent);
        if (!downloadFileResult.isSuccess()) {
            FileResponseUtil.write(response, downloadFileResult);
            return;
        }
        // 下载文件信息
        FileDownloadVO fileDownloadVO = downloadFileResult.getData();
        // 设置下载消息头
        FileResponseUtil.setDownloadFileHeader(response, fileDownloadVO.getMetadata().getFileName(), fileDownloadVO.getMetadata().getFileSize());
        // 下载
        response.getOutputStream().write(fileDownloadVO.getData());
    }

    @Operation(summary = "根据文件id 获取文件信息(有过在线编辑的文件返回最新版本的文件信息)")
    @GetMapping("/file/info/{fileId}")
    public SingleResponse<FileVO> getFileInfoById(@Parameter(name = "文件ID", required = true)
                                                  @PathVariable String fileId) {
        log.info("获取文件信息，fileId: {}", fileId);
        return fileService.getFileInfoById(fileId);
    }

    @Operation(summary = "复制文件（用于模板创建合同等场景）")
    @PostMapping("/file/copy")
    public SingleResponse<FileUploadVO> copyFile(
            @RequestParam String sourceFileId,
            @RequestParam(required = false, defaultValue = "2") Integer folder) {
        UserInfo currentUser = AuthUtil.getCurrentUser();

        return fileService.copyFile(sourceFileId, folder, currentUser);
    }


    @Operation(summary = "批量文件下载：根据fileKey列表打包下载")
    @PostMapping("/file/batchDownload")
    public void batchDownload(
            @Parameter(name = "文件Key列表", required = true)
            @RequestBody List<String> fileKeys,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        log.info("收到批量下载文件请求，文件数量: {}", fileKeys != null ? fileKeys.size() : 0);
        fileService.batchDownloadFiles(fileKeys, request, response);
    }



    @Operation(summary = "合同文件下载：根据fileId和指定格式下载")
    @GetMapping("/file/contract/download-by-id")
    public void downloadContractById(
            @Parameter(description = "文件ID", required = true)
            @RequestParam String fileId,
            @Parameter(description = "下载格式，docx或pdf", required = true)
            @RequestParam String format,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        
        log.info("收到根据fileId下载合同文件请求，fileId: {}, format: {}", fileId, format);
        fileService.downloadContractByFileId(fileId, format, request, response);
    }

    @Operation(summary = "合同文件下载：根据fileKey和指定格式下载")
    @GetMapping("/file/contract/download")
    public void downloadContract(
            @Parameter(description = "文件Key", required = true)
            @RequestParam String fileKey,
            @Parameter(description = "下载格式，docx或pdf",  required = true)
            @RequestParam String format,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        
        log.info("收到根据fileKey下载合同文件请求，fileKey: {}, format: {}", fileKey, format);
        fileService.downloadContractByFileKey(fileKey, format, request, response);
    }
}
